'use strict';

const React = require('react');
const _ = require('lodash');
const hljs = require('highlight.js');
const Markdown = require('markdown-it');
const markdownPlugins = require('../markdown-it-plugins');
function hljsDefineVue(hljs) {
    return {
      subLanguage: "xml",
      contains: [
        hljs.COMMENT("<!--", "-->", {
          relevance: 10,
        }),
        {
          begin: /^(\s*)(<script>)/gm,
          end: /^(\s*)(<\/script>)/gm,
          subLanguage: "javascript",
          excludeBegin: true,
          excludeEnd: true,
        },
        {
          begin: /^(\s*)(<script lang=["']ts["']>)/gm,
          end: /^(\s*)(<\/script>)/gm,
          subLanguage: "typescript",
          excludeBegin: true,
          excludeEnd: true,
        },
        {
          begin: /^(\s*)(<style(\sscoped)?>)/gm,
          end: /^(\s*)(<\/style>)/gm,
          subLanguage: "css",
          excludeBegin: true,
          excludeEnd: true,
        },
        {
          begin: /^(\s*)(<style lang=["'](scss|sass)["'](\sscoped)?>)/gm,
          end: /^(\s*)(<\/style>)/gm,
          subLanguage: "scss",
          excludeBegin: true,
          excludeEnd: true,
        },
        {
          begin: /^(\s*)(<style lang=["']stylus["'](\sscoped)?>)/gm,
          end: /^(\s*)(<\/style>)/gm,
          subLanguage: "stylus",
          excludeBegin: true,
          excludeEnd: true,
        },
      ],
    };
}
hljs.registerLanguage("vue", hljsDefineVue);

class MarkdownView extends React.Component {
    content() {
        const { source, children, pageIndex = '' } = this.props;
        if (source) {
            return <span id={`page${pageIndex}`} dangerouslySetInnerHTML={{ __html: this.renderMarkdown(source) }} />;
        } else {
            return React.Children.map(children, child => {
                if (typeof child === 'string') {
                    return <span dangerouslySetInnerHTML={{ __html: this.renderMarkdown(child) }} />;
                } else {
                    return child;
                }
            });
        }
    }
    renderMarkdown(source) {
        const { page } = this.props;
        if (!this.md) {
            const config = _.get(page, 'config', {});
            this.md = new Markdown({
                breaks: true,
                // Highlight.js expects hljs css classes on the code element.
                // This results in <pre><code class="hljs css javascript">
                langPrefix: 'hljs css ',
                highlight: function(str, lang) {
                    lang = lang || _.get(config, 'highlight.defaultLang');
                    if (lang && hljs.getLanguage(lang)) {
                        try {
                            return hljs.highlight(str, { language: lang }).value;
                        } catch (err) {}
                    }

                    try {
                        return hljs.highlightAuto(str).value;
                    } catch (err) {}

                    return '';
                },
                html: true,
                linkify: true,
            });
            // Register markdown plugins
            markdownPlugins.forEach(function(plugin) {
                plugin(this.md, Object.assign(page, {MarkdownView}));
            }, this);

            // Register custom markdown plugins
            if (config.markdownPlugins) {
                config.markdownPlugins.forEach(function(plugin) {
                    plugin(this.md, Object.assign(page, {MarkdownView}));
                }, this);
            }
        }
        return this.md.render(source);
    }
    render() {
        const Container = this.props.container;
        if (!Container) {
            return this.content();
        }
        return (
            <Container>
                {this.content()}
            </Container>
        );
    }
}

MarkdownView.defaultProps = {
    container: 'div',
};

module.exports = MarkdownView;
